import pandas as pd
import logging

class DataMerger:
    """数据合并子模块
    
    负责在预处理后执行数据合并操作，生成待处理数据
    处理步骤包括字段对齐、数据标记和重复检测
    
    符合项目大纲4.3数据合并阶段的要求
    """
    
    def __init__(self):
        """初始化数据合并器"""
        self.logger = logging.getLogger("data_merging")
        # 定义需要特殊处理的字段
        self.KEY_FIELDS = ["客户简称", "规格型号", "预完工日期"]
        self.AGGREGATE_FIELDS = ["数量"]
        self.JOIN_FIELDS = ["客户订单号", "包装箱方案"]
    
    def merge_task_data(self, task_data, historical_data):
        """合并任务数据（预处理后的任务数据内部合并）
        
        根据项目大纲要求，预处理后执行任务数据的合并操作，生成待处理数据
        当客户简称、规格型号、预完工日期三者相同时，仅对数量字段进行叠加处理
        客户订单号和包装箱方案字段直接从任务数据中复制，多值情况下使用"/"分隔
        其余字段不做特殊处理
        
        Args:
            task_data: 预处理后的任务数据
            historical_data: 预处理后的历史数据（仅用于字段对齐）
            
        Returns:
            合并后的待处理数据
        """
        self.logger.info("执行预处理后的数据合并操作 - 任务数据内部合并")
        
        # 确保输入数据有效
        if task_data is None or task_data.empty:
            self.logger.warning("任务数据为空，无法执行合并操作")
            return pd.DataFrame()
        
        # 1. 字段对齐：确保任务数据包含历史数据的关键字段
        if historical_data is not None and not historical_data.empty:
            # 获取历史数据的所有字段
            historical_columns = historical_data.columns.tolist()
            
            # 为任务数据添加缺失的历史数据字段
            for col in historical_columns:
                if col not in task_data.columns:
                    task_data[col] = pd.NA
        
        # 2. 执行任务数据内部合并
        # 检查关键字段是否存在
        missing_key_fields = [col for col in self.KEY_FIELDS if col not in task_data.columns]
        if missing_key_fields:
            self.logger.error(f"缺少关键字段：{missing_key_fields}，无法执行合并操作")
            return task_data.copy()
        
        # 创建合并后的结果数据框
        merged_data = pd.DataFrame()
        
        # 按照关键字段进行分组
        grouped = task_data.groupby(self.KEY_FIELDS, dropna=False)
        
        # 处理每个分组
        total_groups = len(grouped)
        merged_count = 0
        
        for group_keys, group_data in grouped:
            # 单条记录不需要合并
            if len(group_data) == 1:
                merged_data = pd.concat([merged_data, group_data], ignore_index=True)
                continue
            
            # 合并操作：创建新的记录
            merged_row = group_data.iloc[0].copy()
            
            # 1) 叠加数量字段
            for field in self.AGGREGATE_FIELDS:
                if field in group_data.columns:
                    merged_row[field] = group_data[field].sum()
            
            # 2) 合并客户订单号和包装箱方案字段（多值用"/"分隔）
            for field in self.JOIN_FIELDS:
                if field in group_data.columns:
                    # 获取非空的唯一值
                    unique_values = group_data[field].dropna().unique()
                    if len(unique_values) > 0:
                        merged_row[field] = "/".join(map(str, unique_values))
            
            # 将合并后的记录添加到结果中
            merged_data = pd.concat([merged_data, pd.DataFrame([merged_row])], ignore_index=True)
            merged_count += len(group_data) - 1
        
        self.logger.info(f"数据合并操作完成，共合并{merged_count}条记录，原始记录{len(task_data)}条，合并后记录{len(merged_data)}条")
        return merged_data

    def append_data_sources(self, primary_data, secondary_data, source_label):
        """将次要数据源的数据追加到主要数据源
        
        Args:
            primary_data: 主要数据源
            secondary_data: 次要数据源
            source_label: 次要数据源的标签
            
        Returns:
            追加后的数据
        """
        if secondary_data is None or secondary_data.empty:
            self.logger.warning(f"{source_label}数据为空，无需追加")
            return primary_data
        
        # 确保字段对齐
        primary_columns = primary_data.columns.tolist()
        for col in primary_columns:
            if col not in secondary_data.columns:
                secondary_data[col] = pd.NA
        
        # 只保留主要数据源的字段
        secondary_data = secondary_data[primary_columns]
        
        # 添加来源标记
        secondary_data["数据来源"] = source_label
        
        # 追加数据
        result = pd.concat([primary_data, secondary_data], ignore_index=True)
        self.logger.info(f"已追加{len(secondary_data)}条{source_label}数据")
        
        return result

    def detect_duplicates(self, data, key_columns=None):
        """检测数据中的重复记录
        
        Args:
            data: 待检测的数据
            key_columns: 用于检测重复的关键字段列表，如果为None则使用默认组合
            
        Returns:
            包含重复标记的数据
        """
        if data is None or data.empty:
            return data
        
        # 使用默认关键字段（客户简称+规格型号）
        if key_columns is None:
            key_columns = ["客户简称", "规格型号"]
        
        # 确保所有关键字段都存在
        missing_columns = [col for col in key_columns if col not in data.columns]
        if missing_columns:
            self.logger.warning(f"缺少关键字段：{missing_columns}，无法执行重复检测")
            return data
        
        # 创建唯一键
        unique_key = data[key_columns[0]].astype(str)
        for col in key_columns[1:]:
            unique_key += "_" + data[col].astype(str)
        
        # 检测重复
        duplicate_mask = unique_key.duplicated(keep=False)
        
        if duplicate_mask.any():
            duplicate_count = duplicate_mask.sum()
            self.logger.info(f"发现{duplicate_count}条重复记录")
            
            # 如果备注字段不存在，则创建
            if "备注" not in data.columns:
                data["备注"] = ""
            
            # 为已有的备注添加分隔符
            existing_notes = data["备注"].fillna("")
            has_existing_note = existing_notes != ""
            data.loc[has_existing_note, "备注"] = existing_notes + "；"
            
            # 添加重复标记
            data.loc[duplicate_mask, "备注"] += "重复记录"
        
        return data